﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using FinalProject.BL;
using FinalProject.DAL.Model;

namespace FinalProject.UI
{
    /// <summary>
    /// Interaction logic for OrderPage.xaml
    /// </summary>
    public partial class OrderPage : UserControl, IBasePage
    {
        private Guid _selectedId = Guid.Empty;

        public enum FormMode { NewMode, UpdateMode, Normal };

        public FormMode FormState { get; set; }

        public OrderPage()
        {
            this.InitializeComponent();
            this.InitializeEvents();
            this.InitialItemForCombobox();
            this.txtDocumentNumber.IsReadOnly = true;
            this.grvOderList.RefreshData();
            this.lkuCustomer.PersistenceType = typeof(DAL.Model.Customer);
            this.lkuCustomer.RefreshData();
        }

        private void InitialItemForCombobox()
        {
            this.cmbPaymentMehotd.Items.Add(new { Display = "Cash", Value = OrderManagementBL.PaymentMethod.Cash });
            this.cmbPaymentMehotd.Items.Add(new { Display = "Bank transfer", Value = OrderManagementBL.PaymentMethod.Bank });
            this.cmbPaymentMehotd.DisplayMemberPath = "Display";
            this.cmbPaymentMehotd.SelectedValuePath = "Value";
            this.cmbPaymentMehotd.SelectedIndex = 0;

            this.cmbCurrency.Items.Add(new { Display = "VND", Value = 1 });
            this.cmbCurrency.SelectedIndex = 0;
            this.cmbCurrency.IsReadOnly = true;
            this.cmbCurrency.DisplayMemberPath = "Display";
            this.cmbCurrency.SelectedValuePath = "Value";
            this.cmbCurrency.SelectedIndex = 0;

            this.cmbMaturity.Items.Add(new { Display = "30 Days", Value = 1 });
            this.cmbMaturity.Items.Add(new { Display = "60 Days", Value = 2 });
            this.cmbMaturity.Items.Add(new { Display = "90 Days", Value = 3 });
            this.cmbMaturity.DisplayMemberPath = "Display";
            this.cmbMaturity.SelectedValuePath = "Value";
            this.cmbMaturity.SelectedIndex = 0;
        }

        private void ResetAllValuesControls()
        {
            this.txtDocumentNumber.Text = OrderManagementBL.GetLastestNumber().ToString();
            this.dpkCreateDate.SelectedDate = DateTime.Now;
            this.lkuCustomer.Text = string.Empty;
            this.cmbCurrency.SelectedIndex = 0;
            this.cmbMaturity.SelectedIndex = 0;
            this.cmbPaymentMehotd.SelectedIndex = 0;
            this.dpkCreateDate.SelectedDate = DateTime.Now;
            this.dpkDeliveryDate.SelectedDate = DateTime.Now;
            this.txtDeliveryAddress.Text = string.Empty;
            this.txtNote.Text = string.Empty;
            this.grvItemList.ClearData();
        }

        private bool ValidationData()
        {
            bool result = true;
            if (string.IsNullOrEmpty(this.txtDocumentNumber.Text))
            {
                result = false;
                FormValidation.DisplayWarning(this.txtDocumentNumber, "Please, input number");
            }
            else
                FormValidation.RemoveWarning(this.txtDocumentNumber);

            if (dpkCreateDate.SelectedDate == null ||
                !dpkCreateDate.SelectedDate.HasValue)
            {
                result = false;
                FormValidation.DisplayWarning(this.dpkCreateDate, "Please, this field is amadatory");
            }
            else
                FormValidation.RemoveWarning(this.dpkCreateDate);

            if (lkuCustomer.SelectedId == Guid.Empty)
            {
                result = false;
                Utilities.GetMessageError("Dont have this customer");
            }

            if (!CustomerBL.CanDebit(this.lkuCustomer.SelectedId, Convert.ToDecimal(this.txtTotal.Text)))
            {
                result = false;
                Utilities.GetMessageInfo("Customer is reach maximum debit. Cannot create order");
            }
            result &= this.grvItemList.IsValidData();

            return result;
        }

        private void LoadData(Guid orderId)
        {
            OrderDocument order = OrderManagementBL.LoadById(orderId);
            if (order == null) return;

            this.txtDocumentNumber.Text = order.DocNumber.ToString();
            this.dpkCreateDate.SelectedDate = order.DocDate;
            this.lkuCustomer.SetSelectedValue(order.Customer);
            this.cmbPaymentMehotd.SelectedValue = Enum.Parse(typeof(OrderManagementBL.PaymentMethod), order.PayMode.ToString());
            this.txtDeliveryAddress.Text = order.DocAddress;
            this.dpkDeliveryDate.SelectedDate = order.DeliveryDate;
            this.grvItemList.LoadData(order.Id);
        }

        public void SaveData()
        {
            if (this.ValidationData())
            {
                bool success = OrderManagementBL.InsertOrUpdate(this.GetDocumentUserInput(), this.grvItemList.GetAllEntry());
                if (success)
                {
                    this.FormState = FormMode.Normal;
                    this.ChangeToNormalMode();
                    Utilities.GetMessageInfo("Save success");
                }
                else
                    Utilities.GetMessageError("Cannot save this order");
            }
        }

        private OrderDocument GetDocumentUserInput()
        {
            OrderDocument orderDoc = null;
            if (this.FormState == FormMode.NewMode)
            {
                orderDoc = new OrderDocument();
            }
            else
                orderDoc = OrderManagementBL.LoadById(this._selectedId);

            orderDoc.CustomerId = this.lkuCustomer.SelectedId;
            orderDoc.DocNumber = Convert.ToInt64(this.txtDocumentNumber.Text);
            orderDoc.DocDate = this.dpkCreateDate.SelectedDate ?? DateTime.Now;
            orderDoc.DocAddress = this.txtDeliveryAddress.Text;
            orderDoc.PayMode = (short)this.cmbPaymentMehotd.SelectedValue;
            orderDoc.DeliveryDate = this.dpkDeliveryDate.SelectedDate ?? DateTime.Now;

            return orderDoc;
        }

        public void CancelModified()
        {
            Utilities.SwichToEditMode(this, false);
            this.ChangeToNormalMode();
            this._selectedId = this.grvOderList.GetSelectedId();
            if (this._selectedId != Guid.Empty)
                this.LoadData(this._selectedId);
        }

        public void ChangeToNewMode()
        {
            this.FormState = FormMode.NewMode;
            this.ResetAllValuesControls();
            this.lkuCustomer.IsEnabled = true;
            this.lkuCustomer.Focus();
            this.gbxOrderList.IsEnabled = false;
        }

        public void ChangeToNormalMode()
        {
            this.FormState = FormMode.Normal;
            this.lkuCustomer.IsReadonly = true;
            this.grvOderList.RefreshData();
            this.gbxOrderList.IsEnabled = true;
            this._selectedId = this.grvOderList.GetSelectedId();
        }

        private void InitializeEvents()
        {
            this.lkuCustomer.PreviewTextInput += TextUserChanged;
            this.cmbCurrency.PreviewTextInput += TextUserChanged;
            this.cmbPaymentMehotd.PreviewTextInput += TextUserChanged;
            this.cmbMaturity.PreviewTextInput += TextUserChanged;
            this.dpkDeliveryDate.PreviewTextInput += TextUserChanged;
            this.txtDeliveryAddress.PreviewTextInput += TextUserChanged;
            this.txtNote.PreviewTextInput += TextUserChanged;
            this.txtDocumentNumber.PreviewTextInput += TextUserChanged;
            this.dpkCreateDate.PreviewTextInput += TextUserChanged;
            this.grvItemList.GridValueChaged += grvItemList_GridValueChaged;

            this.grvOderList.SelectionChanged += grvOderList_SelectionChanged;
            this.dpkCreateDate.SelectedDateChanged += dpkCreateDate_SelectedDateChanged;
            this.dpkDeliveryDate.SelectedDateChanged += dpkCreateDate_SelectedDateChanged;
            this.lkuCustomer.ValueChanged += lkuCustomer_ValueChanged;
        }

        void lkuCustomer_ValueChanged(object sender, EventArgs e)
        {
            Guid customerId = this.lkuCustomer.SelectedId;
            Customer cust = CustomerBL.LoadById(customerId);
            if (cust != null)
                this.txtDeliveryAddress.Text = cust.Address;
        }

        void dpkCreateDate_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
        {
            if (sender == this.dpkCreateDate)
                this.dpkDeliveryDate.SelectedDate = this.dpkCreateDate.SelectedDate;
            else
            {
                if (this.dpkDeliveryDate.SelectedDate <= this.dpkCreateDate.SelectedDate)
                {
                    this.dpkCreateDate.SelectedDate = dpkDeliveryDate.SelectedDate;
                }
            }
        }

        void grvOderList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            this._selectedId = this.grvOderList.GetSelectedId();
            this.LoadData(this._selectedId);
        }

        private void grvItemList_GridValueChaged(object sender, EventArgs e)
        {
            this.TextUserChanged(sender, null);
            decimal totalMoney = this.grvItemList.GetTotalAmount();
            decimal totalVat = (totalMoney * Convert.ToDecimal("0.1"));
            this.txtTotalMoney.Text = totalMoney.ToString();
            this.txtTotalVat.Text = totalVat.ToString();
            this.txtTotal.Text = (totalVat + totalMoney).ToString();
        }

        private void TextUserChanged(object sender, System.Windows.Input.TextCompositionEventArgs e)
        {
            // TODO: Add event handler implementation here.
            if (FormState != FormMode.NewMode)
                FormState = FormMode.UpdateMode;
            Utilities.SwichToEditMode(this, true);
        }

    }
}